﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using GL.Tools;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using WAD.Model;
using WAD.DAL;

namespace WAD.WEB.AppCode.Pay.WxPay
{
    /// <summary>
    /// 统一生成订单（暂时只有APP移动支付调用）
    /// </summary>
    public class MakeOrder
    {
        /// <summary>
        /// 生成预付订单
        /// </summary>
        /// <param name="_subject">订单标题</param>
        /// <param name="_body">订单详情</param>
        /// <param name="_notifyUrl">回调地址</param>
        /// <param name="_outTradeNo">订单号</param>
        /// <param name="_money">订单总金额，单位为分</param>
        /// <returns>预付订单信息</returns>
        public static Dictionary<String, object> MekePrepayId(String _subject, String _body, String _notifyUrl, String _outTradeNo, int _money)
        {
            //开放平台产品的AppID
            String appid = WJXConfig.WeixinOpenConfig.APPID;

            //订单标题
            String attach = _subject;

            //订单详情
            String body = _body;

            //商户号
            String mchId = WJXConfig.WeixinOpenConfig.MCHID;

            //不可预料的随机字符串
            String nonceStr = StringHelper.Random(32);

            //回调地址
            String notifyUrl = _notifyUrl;

            //订单号
            String outTradeNo = _outTradeNo;

            //APP和网页支付提交用户端ip,暂时不知道有什么用
            String spbillCreateIp = "113.88.173.170";

            //订单总金额，单位为分
            int totalFee = _money;

            //取值如下：JSAPI，NATIVE，APP
            String tradeType = "APP";

            //api密钥
            String key = WJXConfig.WeixinOpenConfig.KEY;

            //拼接参数
            String qureyString = "appid=" + appid + "&attach=" + attach + "&body=" + body + "&mch_id=" + mchId + "&nonce_str=" + nonceStr + "&notify_url=" + notifyUrl + "&out_trade_no=" + outTradeNo + "&spbill_create_ip=" + spbillCreateIp + "&total_fee=" + totalFee + "&trade_type=" + tradeType + "&key=" + key;

            //生成签名
            String sign = StringHelper.MD5Encrypt(qureyString).ToUpper();

            //生成xml
            String xmlInfo = "<xml><appid>{0}</appid><attach>{1}</attach><body>{2}</body><mch_id>{3}</mch_id><nonce_str>{4}</nonce_str><notify_url>{5}</notify_url><out_trade_no>{6}</out_trade_no><spbill_create_ip>{7}</spbill_create_ip><total_fee>{8}</total_fee><trade_type>{9}</trade_type><sign>{10}</sign></xml>";
            String payInfo = new StringBuilder().AppendFormat(xmlInfo, appid, attach, body, mchId, nonceStr, notifyUrl, outTradeNo, spbillCreateIp, totalFee, tradeType, sign).ToString();

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.mch.weixin.qq.com/pay/unifiedorder");

            request.Method = "POST";
            request.Timeout = 30 * 1000;

            //设置POST的数据类型和长度
            request.ContentType = "text/xml";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(payInfo);
            request.ContentLength = data.Length;

            //往服务器写入数据
            Stream reqStream = request.GetRequestStream();
            reqStream.Write(data, 0, data.Length);
            reqStream.Close();

            //获取服务端返回
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            //获取服务端返回数据
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8"));
            String result = sr.ReadToEnd().Trim();
            sr.Close();

            //读取xml数据
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(result);

            //得到预付订单
            String prepayId = null;

            try
            {
                prepayId = doc.SelectNodes("/xml/prepay_id")[0].InnerText;
            }
            catch
            {
                //生成预支付订单异常,保存日志到数据库
                MLogcat m = new MLogcat() { content = result, type = "微信支付" };
                DaoLogcat.Add(m);
                return null;
            }

            //生成时间戳
            long timestamp = StringHelper.Timestamp();

            //拼接参数
            qureyString = "appid=" + appid + "&noncestr=" + nonceStr + "&package=Sign=WXPay&partnerid=" + mchId + "&prepayid=" + prepayId + "&timestamp=" + timestamp + "&key=" + key; ;
            sign = StringHelper.MD5Encrypt(qureyString).ToUpper();

            //封装
            Dictionary<String, object> map = new Dictionary<String, object>();
            map.Add("appid", appid);
            map.Add("noncestr", nonceStr);
            map.Add("package", "Sign=WXPay");
            map.Add("partnerid", mchId);
            map.Add("prepayid", prepayId);
            map.Add("timestamp", timestamp);
            map.Add("sign", sign);
            return map;
        }
    }
}